/**
 *博尔信基础开发平台
 *<br> 版权声明：厦门博尔信软件有限公司版权所有,违者必究
 *<br> Copyright:  Copyright (c) 2012
 *<br> Company:pearlsoft
 *<br> @author 蒋勇华
 *<br> 2012-5-16
 *<br> @version 1.0
 *————————————————————————————————————
 *修改记录
 *    修改者：
 *    修改时间：
 *    修改原因：
 *——————————————————————————————————————
 */
package com.pearlsoft.webapp.rms.restask.service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.pearlsoft.commons.utils.UUIDUtil;
import com.pearlsoft.rms.VappConfig;
import com.pearlsoft.rms.VcloudManager;
import com.pearlsoft.rms.VcloudManagerImpl;
import com.pearlsoft.rms.VappConfig.VmConfig;
import com.pearlsoft.util.DateUtils;
import com.pearlsoft.webapp.core.dao.RecrodRowMapper;
import com.pearlsoft.webapp.core.dataset.Record;
import com.pearlsoft.webapp.core.dataset.SimpleRecord;
import com.pearlsoft.webapp.core.service.BaseSimpleJdbcService;
import com.pearlsoft.webapp.rms.StepStatus;
import com.pearlsoft.webapp.rms.resapply.service.ResApplyService;
import com.vmware.vcloud.sdk.VCloudException;
import com.vmware.vcloud.sdk.VM;

/**
 *描述：
 * 
 * 
 */
@Service
public class ResTaskService extends BaseSimpleJdbcService {
    private static Log logger = LogFactory.getLog(ResTaskService.class);
    @Autowired
    private VcloudManager vcloudManager;
    @Autowired
    private ResApplyService resApplyService;

    protected VcloudManager getVcloudManager() {
        return this.vcloudManager;
    }

    protected ResApplyService getResApplyService() {
        return this.resApplyService;
    }

    /***
     * 得到所有的资源定时任务列表
     * @return
     */
    public List<Record> getTaskList() {
        String sql = " select taskId,resName,applyer,startDate,endDate,applyId,status,crtTime from rms_restask order by crtTime desc";
        List<Record> list = this.getBaseSimpleJdbcDao().query(sql, new RecrodRowMapper<Record>() {
            @Override
            public Record mapRow(ResultSet rs, int rowNum) throws SQLException {
                SimpleRecord recrod = new SimpleRecord();
                recrod.setValue("taskId", rs.getString(1));
                recrod.setValue("resName", rs.getString(2));
                recrod.setValue("applyer", rs.getString(3));
                recrod.setValue("startDate", rs.getDate(4) == null ? "" : DateUtils.getDateFormat(new Date(rs
                        .getDate(4).getTime()), "yyyy-MM-dd"));
                recrod.setValue("endDate", rs.getDate(5) == null ? "" : DateUtils.getDateFormat(new Date(rs.getDate(5)
                        .getTime()), "yyyy-MM-dd"));
                recrod.setValue("applyId", rs.getString(6));
                recrod.setValue("status", rs.getString(7));
                recrod.setValue("crtTime", rs.getDate(8) == null ? "" : DateUtils.getTimeStr(new Date(rs
                        .getTimestamp(8).getTime())));
                return recrod;
            }
        });
        return list;
    }

    public Record run(Record record) {
    	logger.info(" 开始执行资源启动任务");
        Record result = new SimpleRecord();
        result.setValue("success", "1");
        result.setValue("error", "");
        String taskId = (String) record.getValue("taskId");
        String applyId = (String) record.getValue("applyId");
        try {
            Record applyObj = this.getResApplyService().getById(applyId);
            String eName = (String) applyObj.getValue("eName");
            List<Map> hostList = (List<Map>) applyObj.getValue("hostList");
            VappConfig config = new VappConfig(eName);
            config.setOrgName("test");
            config.setVdcName("test");
            for (Map map : hostList) {
                String hostName = (String) map.get("hostName");
                String opsName = (String) map.get("opsName");
	        	String hostIp = (String) map.get("hostIp");
	        	List<String> hostIpList = new ArrayList<String>();
	        	if(!StringUtils.isBlank(hostIp)){
	        		String[] ips = hostIp.split(",");
	        		for(int i=0;i<ips.length;i++){
	        			String ip = ips[i];
	        			if(!StringUtils.isBlank(ip)){
	        				hostIpList.add(ip);
	        			}
	        		}
	        	}
                
                int intCups = Integer.parseInt((String) map.get("cups"));
                int intNetcards = Integer.parseInt((String) map.get("netcards"));
                String memoryunit = (String) map.get("memoryunit");
                String memory = (String) map.get("memory");
                int intMemory = 0;
                if ("0".equalsIgnoreCase(memoryunit)) {//M
                    intMemory = Integer.parseInt(memory);
                } else if ("1".equalsIgnoreCase(memoryunit)) {//G
                    intMemory = Integer.parseInt(memory) * 1024;
                }
                String storageunit = (String) map.get("storageunit");
                String storage = (String) map.get("storage");
                int intStorage = 0;
                if ("0".equalsIgnoreCase(storageunit)) {//M
                    intStorage = Integer.parseInt(storage);
                } else if ("1".equalsIgnoreCase(storageunit)) {//G
                    intStorage = Integer.parseInt(storage) * 1024;
                } else if ("2".equalsIgnoreCase(storageunit)) {//T
                    intStorage = Integer.parseInt(storage) * 1024 * 1024;
                }
                config.addVm(hostName, opsName, intCups, intNetcards, intMemory, intStorage, 8,hostIpList);
            }
            logger.info("开始创建资源任务");
            List<VM> vmList = this.getVcloudManager().createVapp(config);
            logger.info("创建资源任务结束");
            this.updateTaskStatus(taskId, "1");
            this.updateApplyStepStatus(applyId, StepStatus.RUNNED);
            this.createRes(applyId, config);
            logger.info("开始启动主机List");
            this.startResVm(vmList);
            logger.info("启动主机List结束");
        } catch (Exception e) {
            result.setValue("success", "0");
            result.setValue("error", e.getMessage());
            logger.info("执行资源启动任务成功失败;原因:"+e.getMessage());
        }
        logger.info("执行资源启动任务成功完成");
        return result;
    }
    private void startResVm(List<VM> vmList){
    	if( vmList!=null && vmList.size()>0 ){
    		for( VM vm:vmList){
    			try {
					this.getVcloudManager().startVM(vm);
				} catch (VCloudException e) {
					e.printStackTrace();
				}
    		}
    	}
    }
    private String getHostIp(String hostName, VappConfig config) {
        StringBuilder sb = new StringBuilder();
        List<VmConfig> list = config.getVmConfig();
        for (VmConfig vmConfig : list) {
            if (vmConfig.getName().equalsIgnoreCase(hostName)) {
                List<String> ips = vmConfig.getIpAddress();
                for (String ip : ips) {
                    sb.append(ip).append(",");
                }
            }
        }
        String temp = sb.toString();
        if (temp.length() > 0) {
            temp = temp.substring(0, temp.length() - 1);
        }
        return temp;
    }

    public void createRes(String applyId, VappConfig config) {
        String resSql = "";
        resSql = " insert into rms_myres (resId,applyId,ownerId,resName,eName,resDesc,startDate,endDate,status) ";
        resSql = resSql + " values (:resId,:applyId,:ownerId,:resName,:eName,:resDesc,:startDate,:endDate,:status)";
        String hostSql = " insert into rms_myhost (hostId,resId,hostName,hostDesc,hostIp,account,pwd,opsSeries,opsName,cups,memory,memoryunit,storage,storageunit,netcards) ";
        hostSql = hostSql
                + " values (:hostId,:resId,:hostName,:hostDesc,:hostIp,:account,:pwd,:opsSeries,:opsName,:cups,:memory,:memoryunit,:storage,:storageunit,:netcards)";
        Record applyObj = this.getResApplyService().getById(applyId);

        String resId = UUIDUtil.get();

        Map<String, Object> resParam = new HashMap<String, Object>();
        //Map<String, Object> hostParam = new HashMap<String, Object>();
        //resId,applyId,ownerId,resName,resDesc,startDate,endDate,status
        resParam.put("resId", resId);
        resParam.put("applyId", (String) applyObj.getValue("applyId"));
        resParam.put("ownerId", (String) applyObj.getValue("authorId"));
        resParam.put("resName", (String) applyObj.getValue("resName"));
        resParam.put("eName", (String) applyObj.getValue("eName"));
        resParam.put("resDesc", (String) applyObj.getValue("resDesc"));
        try {
            resParam.put("startDate", DateUtils.getDate((String) applyObj.getValue("startDate"), "yyyy-MM-dd"));
            resParam.put("endDate", DateUtils.getDate((String) applyObj.getValue("endDate"), "yyyy-MM-dd"));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        resParam.put("status", "0");
        this.getBaseSimpleJdbcDao().update(resSql, resParam);

        List<Map> hostList = (List<Map>) applyObj.getValue("hostList");
        for (Map map : hostList) {
            String hostId = UUIDUtil.get();
            String hostName = (String) map.get("hostName");
            Map<String, Object> hostParam = new HashMap<String, Object>();
            //hostId,resId,hostName,hostDesc,hostIp,account,pwd,
            //opsSeries,opsName,cups,memory,memoryunit,storage,storageunit,netcards
            hostParam.put("hostId", hostId);
            hostParam.put("resId", resId);
            hostParam.put("hostName", map.get("hostName"));
            hostParam.put("hostDesc", map.get("hostDesc"));
            hostParam.put("hostIp", this.getHostIp(hostName, config));
            hostParam.put("account", "administrator");
            hostParam.put("pwd", "abc123..");
            hostParam.put("opsSeries", map.get("opsSeries"));
            hostParam.put("opsName", map.get("opsName"));
            hostParam.put("cups", map.get("cups"));
            hostParam.put("memory", map.get("memory"));
            hostParam.put("memoryunit", map.get("memoryunit"));
            hostParam.put("storage", map.get("storage"));
            hostParam.put("storageunit", map.get("storageunit"));
            hostParam.put("netcards", map.get("netcards"));
            this.getBaseSimpleJdbcDao().update(hostSql, hostParam);
        }

    }

    /***
     * 停止
     * @param record
     */
    public void stop(Record record) {
        String taskId = (String) record.getValue("taskId");
        this.updateTaskStatus(taskId, "2");
    }

    /**
     * 更新任务状态
     * @param taskId
     * @param taskStatus
     */
    private void updateTaskStatus(String taskId, String taskStatus) {
        String sqlTask = " update rms_restask set status=:status where taskId=:taskId ";
        Map<String, String> param1 = new HashMap<String, String>();
        param1.put("taskId", taskId);
        param1.put("status", taskStatus);
        this.getBaseSimpleJdbcDao().update(sqlTask, param1);
    }

    /**
     * 更新申请步骤状态
     * @param applyId
     * @param stepStatus
     */
    private void updateApplyStepStatus(String applyId, String stepStatus) {
        String sql = " update rms_flowstep  set stepstatus=:stepstatus " + "where applyId=:applyId and stepType='0' ";
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("applyId", applyId);
        param.put("stepstatus", stepStatus);
        this.getBaseSimpleJdbcDao().update(sql, param);
    }

    /***
     * 主机硬件参数更新
     * @param vdcName
     * @param vappName
     * @param vmName
     * @param cpu
     * @param memory
     * @param appendDiskHard
     * @throws Exception
     */
    public void updateHostParam(String vdcName, String vappName, String vmName, String cpu, String memory,
            String appendDiskHard) throws Exception {
        this.getVcloudManager().updateVm("test", vdcName, vappName, vmName, Integer.parseInt(cpu),
                Integer.parseInt(memory), 0, Integer.parseInt(appendDiskHard));
    }

}
